package com.sky.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.*;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.exception.SetmealEnableFailedException;
import com.sky.mapper.*;
import com.sky.result.PageResult;
import com.sky.service.DishService;
import com.sky.vo.DishVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;


@Service
public class DishServiceImpl implements DishService {

    @Autowired
    DishMapper dishMapper;

    @Autowired
    DishFlavorMapper dishFlavorMapper;

    @Autowired
    CategoryMapper categoryMapper;

    @Autowired
    SetmealDishMapper setmealDishMapper;


    @Autowired
    SetmealMapper setmealMapper;

    @Autowired
    RedisTemplate redisTemplate;


    /**
     * 添加菜品
     *
     * @param dishDTO
     */
    @Transactional
    @Override
    public void saveDishAndDishFlavor(DishDTO dishDTO) {
        // 添加菜品
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);
        dishMapper.save(dish);

        // 添加菜品的口味
        List<DishFlavor> flavors = dishDTO.getFlavors();
        List<DishFlavor> flavorList = flavors.stream().map(dishFlavor -> {
            dishFlavor.setDishId(dish.getId());
            return dishFlavor;
        }).collect(Collectors.toList());
        dishFlavorMapper.saveFlavors(flavorList);
    }


    /**
     * 分页查询菜品
     *
     * @param dishPageQueryDTO
     * @return
     */
    @Override
    public PageResult page(DishPageQueryDTO dishPageQueryDTO) {
        PageHelper.startPage(dishPageQueryDTO.getPage(), dishPageQueryDTO.getPageSize());
        List<Dish> dishList = dishMapper.page(dishPageQueryDTO);
        PageInfo<Dish> dishPageInfo = new PageInfo<>(dishList);
        long total = dishPageInfo.getTotal();

        // 查询菜品对应的分类并封装到dishVO中
        List<DishVO> voList = dishList.stream().map(dish -> {
            Category category = categoryMapper.findByCategoryId(dish.getCategoryId());
            DishVO dishVO = new DishVO();
            BeanUtils.copyProperties(dish, dishVO);
            dishVO.setCategoryName(category.getName());
            return dishVO;
        }).collect(Collectors.toList());
        return new PageResult(total, voList);
    }

    /**
     * 删除菜品
     *
     * @param ids
     */
    @Override
    @Transactional
    public void delByIds(List<Long> ids) {
        // 状态不能为启售
        ids.forEach(id -> {
            Dish dish = dishMapper.findById(id);
            if (dish.getStatus() == 1) {
                throw new DeletionNotAllowedException(MessageConstant.DISH_ON_SALE);
            }
        });

        // 菜品不能和套餐相关联
        List<Long> setmealIds = setmealDishMapper.findSetmealfindByDishIds(ids);
        if (setmealIds != null && setmealIds.size() > 0) {
            throw new DeletionNotAllowedException(MessageConstant.DISH_BE_RELATED_BY_SETMEAL);
        }
        // 删除菜品
        dishMapper.delByIds(ids);
        // 再删除菜品对应的口味
        ids.forEach(id -> {
            dishFlavorMapper.delByDishId(id);
        });
    }

    /**
     * 根据id查询
     *
     * @param id
     * @return
     */
    @Override
    public DishVO findById(Long id) {
        Dish dish = dishMapper.findById(id);
        DishVO dishVO = new DishVO();
        BeanUtils.copyProperties(dish, dishVO);
        Category category = categoryMapper.findByCategoryId(dish.getCategoryId());
        dishVO.setCategoryName(category.getName());
        List<DishFlavor> dishFlavorList = dishFlavorMapper.findDishFlavorByDishId(id);
        dishVO.setFlavors(dishFlavorList);
        return dishVO;
    }

    /**
     * 修改菜品
     *
     * @param dishDTO
     */
    @Override
    @Transactional
    public void update(DishDTO dishDTO) {
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);
        // 更新菜品表
        dishMapper.update(dish);
        setmealDishMapper.updateByDish(dish);
        // 更新菜品口味 (更新就是先删除再添加)
        // 先把之前的删除了
        dishFlavorMapper.delByDishId(dish.getId());
        // 然后在把新的重新添加进去
        List<DishFlavor> flavors = dishDTO.getFlavors();
        // 判断前端传来的口味是否为空，为空就不用执行添加
        if (flavors == null || flavors.size() == 0) {
            return;
        }
        // 如果这个dishFlavor的value为null，就把这个口味删除
        for (int i = 0; i < flavors.size(); i++) {
            String value = flavors.get(i).getValue();
            if (value == null || value.equals("[]") || value.length() <= 2) {
                flavors.remove(i);
            }
        }
        List<DishFlavor> flavorList = flavors.stream().map(dishFlavor -> {
            dishFlavor.setDishId(dish.getId());
            return dishFlavor;
        }).collect(Collectors.toList());
        dishFlavorMapper.saveFlavors(flavorList);
    }


    /**
     * 启售和停售
     *
     * @param status
     * @param id
     */
    @Override
    @Transactional
    public void updateStatus(Integer status, Long id) {
        Dish dish = Dish.builder().status(status)
                .id(id).build();
        dishMapper.update(dish);
        // 清菜品的缓存
        Dish dbDish = dishMapper.findById(id);
        String DISH_UPDATE = "DISH_" + dbDish.getCategoryId();
        redisTemplate.delete(DISH_UPDATE);

        // 如果把菜品的状态改为0, 那么就把菜品相关的套餐状态也改成0
        if (status == StatusConstant.DISABLE) {
            ArrayList<Long> ids = new ArrayList<>();
            ids.add(id);
            // 通过菜品id找到连接表中的套餐id
            List<Long> list = setmealDishMapper.findSetmealfindByDishIds(ids);
            // 遍历找到每个套餐，把套餐的状态改成0
            for (Long setmealId : list) {
                Setmeal setmeal = setmealMapper.findById(setmealId);
                setmeal.setStatus(status);
                setmealMapper.updateSetmeal(setmeal);
                // 套餐的状态也修改了，就要清缓存
                String SETMEAL_UPDATE = "SETMEAL_" + setmeal.getCategoryId();
                redisTemplate.delete(SETMEAL_UPDATE);
            }
        }

    }


    /**
     * 根据分类Id查询菜品
     *
     * @param categoryId
     * @return
     */
    @Override
    public List<Dish> findByCategoryId(Long categoryId) {
        List<Dish> list = dishMapper.findByCategoryId(categoryId);
        return list;
    }

    @Override
    public List<DishVO> listWithFlavor(DishDTO dishDTO) {
        // 查到这个分类对应的所有菜品
        List<Dish> dishList = dishMapper.findDishesByCid(dishDTO);

        List<DishVO> dishVOList = new ArrayList<>();
        for (Dish d : dishList) {
            DishVO dishVO = new DishVO();
            BeanUtils.copyProperties(d, dishVO);
            // 把口味封装到每个菜品中
            // 根据菜品id查询对应的口味
            List<DishFlavor> flavors = dishFlavorMapper.findDishFlavorByDishId(d.getId());

            dishVO.setFlavors(flavors);
            dishVOList.add(dishVO);
        }

        return dishVOList;

    }
}
